
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Globalization;
using Swaf.BizObj;
using Swaf.BizRule;
using Swaf.Logging;
using Swaf.Resource;
using Swaf.Container;
using Swaf.Config;
using Swaf.Gui;
using Swaf.Security;

namespace Swaf
{
	/// <summary>
	/// The main entry point for accessing components of the framework.  This interface
	/// provides basic properties for the various core components of the framework, as well
	/// as the basic application and session specific data dictionaries.</summary>
	/// <remarks>
	/// This interface is intended to provide a basic abstraction to how the application
	/// got started and configured from the various users of it.  The <c>appData</c> and
	/// <c>sessionData</c> act as simple properties so that accessing them will always work
	/// properly in both single user and multi user environments.
	/// <p>
	/// When this interface is being used in a multi-user environment, client code should
	/// always be able to assume that the <c>sessionData</c> is specific to the user who triggered
	/// the code being called (which could be a simple timer if being used by a batch processing
	/// environment).  The <c>appData</c> is global per application object regardless of the user
	/// who trigger the code execution.  In this respect, the two data dictionaries are
	/// identical to the way that the application and session variables work in the <i>ASP</i>
	/// and <i>ASP.NET</i> environments.</p>
	/// </remarks>
	/// <see>Application class</see>
	public interface IApplication
	{
		IAudit Audit{get;}
		ILog Log{get;}
		ITrace Trace{get;}

		/// <summary>
		/// provides get only access to the single instance of <c>IBizObjManager</c> for the
		/// given application environment.</summary>
		IBizObjManager bizObjMgr{get;}

		/// <summary>
		/// Provides get only access to the single instance of <c>IRuleManager</c> for the
		/// given application enviornment.</summary>
		IRuleManager ruleMgr{get;}

		/// <summary>
		/// Provides get only access to the single instance of <c>IResourceManager</c> for the
		/// given application environment.</summary>
		IResourceManager resMgr{get;}

		IGuiManager guiMgr{get;}

		/// <summary>
		/// Provides get only access to the single instance of <c>ISecurityManager</c> for the given 
		/// application environment.
		/// </summary>
		ISecurityManager securityMgr{get;}
		/// <summary>
		/// Provides get only access to the single application data dictionary for the given
		/// application environment that is used to store "global" data that is not specific to
		/// a given "user session".</summary>
		IMap appData{get;}

		/// <summary>
		/// Provides get only access to the "user session" specific session data dictionary that
		/// is used to store data specific to a given user.</summary>
		IMap sessionData{get;}
		/// <summary>
		/// Provides a string containing the Guid (or other identifier) for the current session
		/// </summary>
		string sessionId{get;}
		/// <summary>
		/// returns a predefined class factory associated with the specific <c>factoryName</c>
		/// or returns null if no factory is defined with the give name.</summary>
		IDictionary factory{get;}

		/// <summary>
		/// returns a factory manager that exposes a collection of defined factories that can then
		/// be used to access individual factory elements.
		/// </summary>
		IFactoryManager factories{get;}

		bool isValidSession{get;}
		ISessionInfo sessionInfo{get;}
		bool isTiedToRemoteGlobalApp{get;set;}

		bool inBrowseMode{get;}
	}
	public interface ISessionInfo
	{
		bool isValidSession{get;set;}
		string sessionId{get;set;}
		string principalInstanceId{get;set;}
		string principalUserName{get;set;}
		INameAddressSupport additionalInfo{get;set;}
		bool principalWasReset { get; }
	}
	public interface IApplicationChild : IApplication
	{
		void setupForConfig(IApplication app, IConfigManager config);
	}

	public interface ISessionAppManagement
	{
		/// <summary>
		/// When being used in a multi-user environment, this returns an <c>IApplication</c> instance
		/// specific to a given user.</summary>
		/// <remarks>This is not a full application object, but a light session object
		/// that only contains its own <c>sessionData</c> data dictionary and deligates everything else to 
		/// the main application level <c>IApplication</c> instance.
		/// <p>When being used in the <i>ASP</i> or <i>ASP.NET</i> environments, it is
		/// ok to store the returned <c>IApplication</c> instance in the
		/// <i>ASP</i> or <i>ASP.NET</i> session variable to maintain state for user sessions
		/// accross page requests.  It is also ok to call this method multiple times with the
		/// same <c>sessionKey</c>.  When a requestion for a session application comes in with
		/// a sessionKey that already has an instance of <c>IApplication</c>, the same instance
		/// is returned.  It is safe to use this method in that way.</p>
		/// </remarks>
		/// <param name="sessionKey">The unique key for the given user session this <i>IApplication</i>
		/// is for.</param>
		/// <returns>The <c>IApplication</c> specific to the given <c>sessionKey</c>.</returns>
		IApplication createSessionApplication(string sessionKey);

        IApplication createSessionApplication(string sessionKey, bool isTiedToGlobalApp);
        IApplication createSessionApplication(string sessionKey, bool isTiedToGlobalApp, IDictionary startingSessionValues);
        /// <summary>
		/// Shortcut method for creating a new session application with a preset security principal.
		/// </summary>
		/// <param name="sessionKey">The unique key for the given user session this <i>IApplication</i>
		/// is for.</param>
		/// <param name="currentPrincipal">The security principal instance to be used as the current
		/// security context for this session application</param>
		/// <returns>The <c>IApplication</c> specific to the given <c>sessionKey</c>.</returns>
		IApplication createSessionApplication(string sessionKey, ISecurityPrincipal currentPrincipal);
        IApplication createSessionApplication(string sessionKey, bool isTiedToGlobalApp, ISecurityPrincipal currentPrincipal);
        IApplication createSessionApplication(string sessionKey, bool isTiedToGlobalApp, ISecurityPrincipal currentPrincipal, IDictionary startingSessionValues);
        /// <summary>
		/// When being used in a multi-user environment, this should be called to single to the
		/// framework that the given user session is being terminated.
		/// </summary>
		/// <remarks>
		/// It is important to call this method in order for the framework to release its references
		/// to the <c>IApplication</c> object associated with the user session.
		/// <p>When being used in the <i>ASP</i> or <i>ASP.NET</i> environments, it is appropriate
		/// to call this method in the <i>Session End</i> event of the <c>Global.asa</c> or
		/// <c>Global.asax</c>.</p></remarks>
		/// <param name="sessionKey">The unique key for the given user session that is being
		/// terminated.</param>
		void appSessionComplete(string sessionKey);

		IApplication getExistingSession(string sessionKey);
		/// <summary>
		/// Method to execute a rule call.  These overrides should handle creating or retrieving a session as well as
		/// making the rule call
		/// </summary>
		/// <param name="sessionId"></param>
		/// <param name="userName"></param>
		/// <param name="additionalInfo"></param>
		/// <param name="instanceId"></param>
		/// <param name="methodName"></param>
		/// <param name="ruleParams"></param>
		/// <param name="multiCall"></param>
		/// <returns></returns>
		IResults executeRule(string sessionId, bool isTiedToGlobalApp, string userName, INameAddressSupport additionalInfo, string instanceId, string currentCulture, 
			string methodName, ICollection ruleParams, bool multiCall);
		IResults executeRule(string sessionId, bool isTiedToGlobalApp, string userName, INameAddressSupport additionalInfo, string instanceId, string currentCulture,
			string methodName, object ruleParams);
	}

	/// <summary>
	/// This interface is meant to be used by client hosting environments to gain access to
	/// application management type features of the application environment.</summary>
	/// <remarks>
	/// When being used in a multi-user client hosting environment such as <i>ASP</i> or
	/// <i>ASP.NET</i>, this interface is an important mechanism for creating new "user sessions"
	/// that result in multiple <c>sessionData</c> data dictionaries to be created, one for each
	/// user session.
	/// <p>It is important for multi-user clients to signal the end of a user session
	/// by calling the <c>appSessionComplete</c> method as appropriate.</p></remarks>
	public interface IAppManagement : ISessionAppManagement
	{
		IDictionary Sessions{get;}

		void shutdown();

		event AppShutdownRequest OnAppShutdown;
		event AppStartRequest OnAppStart;
		event SessionShutdownRequest OnSessionShutdown;
		event SessionStartRequest OnSessionStart;
	}

	public delegate void AppShutdownRequest(IApplication app);
	public delegate void AppStartRequest(IApplication app);
	public delegate void SessionShutdownRequest(IApplication app);
	public delegate void SessionStartRequest(IApplication app);

	public interface IFactoryManager
	{
		IClassFactory this[string factoryName]{get;}
	}
}